package order

import (
	"github.com/gin-gonic/gin"
	"github.com/shopspring/decimal"
	"matcher/pkg/core"
	"matcher/pkg/lib/helper"
	"matcher/pkg/lib/merror"
)

func MappingURL(R *gin.Engine) {
	R.GET("/market/depth", Depth)
	R.POST("/order/buy", Buy)
	R.POST("/order/sell", Sell)
	R.POST("/order/cancel", Cancel)
}

type DepthRequest struct {
	Symbol string `form:"symbol"`
}

func Depth(ctx *gin.Context) {
	var inputs = &DepthRequest{}
	if err := ctx.Bind(inputs); err != nil {
		helper.Error(ctx, merror.ParamError)
		return
	}

	idx, ok := core.Symbol2Idx[inputs.Symbol]
	if !ok {
		helper.Error(ctx, merror.ParamError)
		return
	}

	var depth = core.Matchers[idx].GetDepth()
	helper.Success(ctx, depth, nil)
}

type BuyRequest struct {
	Uid    int64           `json:"uid"`
	Symbol string          `json:"symbol"`
	Price  decimal.Decimal `json:"price"`
	Amount decimal.Decimal `json:"amount"`
}

func Buy(ctx *gin.Context) {
	var inputs = &BuyRequest{}
	if err := ctx.Bind(inputs); err != nil {
		helper.Error(ctx, merror.ParamError)
		return
	}

	idx, ok := core.Symbol2Idx[inputs.Symbol]
	if !ok {
		helper.Error(ctx, merror.ParamError)
		return
	}

	core.Matchers[idx].Buy(&core.Order{
		Uid:    inputs.Uid,
		Price:  inputs.Price,
		Amount: inputs.Amount,
		Time:   helper.MTS(),
	})
	helper.Success(ctx, nil, nil)
}

type SellRequest struct {
	Uid    int64           `json:"uid"`
	Symbol string          `json:"symbol"`
	Price  decimal.Decimal `json:"price"`
	Amount decimal.Decimal `json:"amount"`
}

func Sell(ctx *gin.Context) {
	var inputs = &SellRequest{}
	if err := ctx.Bind(inputs); err != nil {
		helper.Error(ctx, merror.ParamError)
		return
	}

	idx, ok := core.Symbol2Idx[inputs.Symbol]
	if !ok {
		helper.Error(ctx, merror.ParamError)
		return
	}

	core.Matchers[idx].Sell(&core.Order{
		Uid:    inputs.Uid,
		Price:  inputs.Price,
		Amount: inputs.Amount,
		Time:   helper.MTS(),
	})
	helper.Success(ctx, nil, nil)
}

type CancelRequest struct {
	Symbol string `json:"symbol"`
	ID     uint64 `json:"id"`
}

func Cancel(ctx *gin.Context) {
	var inputs = &CancelRequest{}
	if err := ctx.Bind(inputs); err != nil {
		helper.Error(ctx, merror.ParamError)
		return
	}
	idx, ok := core.Symbol2Idx[inputs.Symbol]
	if !ok {
		helper.Error(ctx, merror.ParamError)
		return
	}
	core.Matchers[idx].Cancel(inputs.ID)
	helper.Success(ctx, nil, nil)
}
